package com.wellwan.cloud.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.exception.HystrixBadRequestException;
import com.wellwan.cloud.entity.User;
import com.wellwan.cloud.feignclient.UserFeignClient;
import feign.Client;
import feign.Contract;
import feign.Feign;
import feign.auth.BasicAuthRequestInterceptor;
import feign.codec.Decoder;
import feign.codec.Encoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.netflix.feign.FeignClientsConfiguration;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.Objects;

/**
 * Copyright (C),微动天下
 * FileName: MovieController
 * Author:   maokai
 * Date:     2020/2/25 9:47
 * Description:
 */
@Import(FeignClientsConfiguration.class)
@RestController
@Slf4j
public class MovieController {
//    @Autowired
    private UserFeignClient userUserFeignClient;
    private UserFeignClient adminUserFeignClient;

    @Value("${user.userServiceUrl}")
    private String serviceHost ="http://microservice-provider-user-with-auth/";


    @Autowired
    public MovieController(Decoder decoder, Encoder encoder, Client client, Contract contract) {
        this.userUserFeignClient = Feign.builder()
                .client(client)
                .encoder(encoder)
                .decoder(decoder)
                .contract(contract)
                .requestInterceptor(new BasicAuthRequestInterceptor("user", "password1"))
                .target(UserFeignClient.class,serviceHost);
        this.adminUserFeignClient = Feign.builder()
                .client(client)
                .encoder(encoder)
                .decoder(decoder)
                .contract(contract)
                .requestInterceptor(new BasicAuthRequestInterceptor("admin", "password2"))
                .target(UserFeignClient.class,serviceHost);

    }
    @GetMapping(value = "/user-user/{id}",produces = MediaType.APPLICATION_JSON_VALUE)
    public User findByIdUser(@PathVariable Long id) throws JsonProcessingException {
        User user = userUserFeignClient.findById(id);
        ObjectMapper objectMapper = new ObjectMapper();
        System.out.println(objectMapper.writeValueAsString(user));
        System.out.println();
        return user;
    }
    @GetMapping(value = "/user-admin/{id}",produces = MediaType.APPLICATION_JSON_VALUE)
    public User findByIdAdmin(@PathVariable Long id) {
        User user = adminUserFeignClient.findById(id);
        return user;
    }

    @PostMapping(value = "/upload",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String upload(MultipartFile file) {
        if (Objects.isNull(file)) {
            throw new RuntimeException("文件不存在");
        }
        String s = userUserFeignClient.handleFileUpload(file);
        return s;
    }

    /**
     * ignoreExceptions 配置即使发生异常也不会执行 findByIdFallBack
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @HystrixCommand(
            commandProperties = {
            //属性配置其他属性配置在 HystrixPropertiesManager 这个类中
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "5000"),
            @HystrixProperty(name="metrics.rollingStats.timeInMilliseconds",value = "5000"),
            @HystrixProperty(name="execution.isolation.strategy",value = "THREAD"),//隔离级别
//            @HystrixProperty(name="coreSize",value = "1"),
//            @HystrixProperty(name="maxQueueSize",value = "10")
            },
            //ignoreExceptions 配置即使发生异常也不会执行 findByIdFallBack
            ignoreExceptions = {IllegalArgumentException.class, HystrixBadRequestException.class}
            )
    public User findById(@PathVariable Long id) {
        User user = userUserFeignClient.findById( id);
        return user;
    }

//    public User findByIdFallBack(Long id, Throwable exception) {
//        log.error("异常信息------->{}",exception.getMessage());
//        User user = new User();
//        user.setId(-1L);
//        return user;
//    }
}
